<?php
/**
 * @author jonathan poelen <jonathan.poelen@gmail.com>
 * @version 1.0: jo_link_noir
 * @date 04-06-2010
 */
abstract class SW_Structure_DAO_Planet extends SW_Structure_DAO
{
	/** @var string : nom de la table planète*/
	protected $tablePlanet;


	/**
	 * @param string $tableReferencingStructure : table qui pointe vers les référence de la table structure
	 * @param string $tableStructure : nom de la table structure
	 * @param string $tableList = null : nom de la table list. Si non précisé $tableStructure.'_list'
	 * @param string $tablePlanet = null : nom de la table planète. Si null alors = 'planet'
	 * @param string $refPlayer = null : référence de la table structure vers la table player (si null alors = ref_player)
	 * @param string $refPlanet = null : référence de la table structure vers une autre table
	 * @param string $refStructure = null : référence de la table list vers la table structure
	 * @param PDO $pdo = null : si null alors = SW_DAO::getDB()
	 */
	public function __construct(
		$tableReferencingStructure,
		$tableStructure,
		$tableList = null,
		$tablePlanet = null,

		$refPlayer = null,
		$refPlanet = null,
		$refStructure = null,

		PDO $pdo = null
	)
	{
		parent::__construct($tableReferencingStructure, $tableStructure, $tableList, $refPlayer, $refPlanet, $refStructure, $pdo);
		$this->tablePlanet = '`'.($tablePlanet ? $tablePlanet : 'planet').'`';
	}

	/**
	 * Ajoute une liste de construction et retourne son id
	 * @param int $id_structure
	 * @param int $level
	 * @param int $duration
	 * @param int $time_end
	 * @param int $id_planet
	 * @return int
	 */
	protected function insertList($id_structure, $level, $duration, $time_end, $id_planet)
	{
		$method = $this->nameMethodList(__METHOD__);
		if (!isset(self::$queries[$method]))
			$this->prepare($method, 'INSERT INTO '.$this->tableList.'('.$this->refStructure.', level, duration, time_end) VALUES(?,?,?,?)');

		self::$queries[$method]->execute(
			array($id_structure, $level, $duration, $time_end)
		);

		return (int)$this->pdo->lastInsertId();
	}

	/**
	 * Ajoute une $id_user et retourne son id d'enregistrement
	 * @param int $id_planet
	 * @param int $group
	 * @param int $level
	 * @return int
	 */
	protected function insertElement($id_planet, $group, $level)
	{
		$method = $this->nameMethodStructure(__METHOD__);
		if (!isset(self::$queries[$method]))
			$this->prepare($method, 'INSERT INTO '.$this->tableStructure.'('.$this->refPlanet.', `group`, level) VALUES(?,?,?)');

		self::$queries[$method]->execute(
			array($id_planet, $group, $level)
		);

		return (int)$this->pdo->lastInsertId();
	}

	/**
	 * @param int $idPlanet
	 * @param array $groups
	 * @return array : {SW_Structure_Element, ...}
	 */
	public function selectElementInPlanet($idPlanet, array $groups)
	{
		$sth = $this->pdo->query(
			'SELECT id, `group`, level FROM '.$this->tableStructure.' WHERE '.$this->refPlanet.'='.((int)$idPlanet).' AND `group` IN('.explode(',',$groups).')',
			PDO::FETCH_OBJ
		);

		$elements = array();
		while ($e = $sth->fetchObject())
			$elements[] = $this->newElement($e->id, $e->group, $e->level, $idPlanet);
		return $elements;
	}

	/**
	 * @param int $id_user
	 * @return array : {ref_planet => {SW_Structure_Element, ...}, ...}
	 */
	public function selectAll($id_user)
	{
		$sth = $this->pdo->query(
			'SELECT _s.id as id, _s.'.$this->refPlanet.' as ref_planet, `group`, level FROM '.$this->tableStructure.' as _s
			JOIN '.$this->tablePlanet.' as _p ON _s.'.$this->refPlanet.'=_p.id
			WHERE '.$this->refPlayer.'='.((int)$id_user),
			PDO::FETCH_OBJ
		);

		$elements = array();
		while ($e = $sth->fetchObject())
		{
			$p = (int)$e->ref_planet;
			if (false === isset($elements[$p]))
				$elements[$p] = array();
			$elements[$p][] = $this->newElement($e->id, $e->group, $e->level, $p);
		}

		return $elements;
	}

	/**
	 * @param int $idPlanet
	 * @return array : {SW_Structure_Element, ...}
	 */
	public function selectAllInPlanet($idPlanet)
	{
		$method = $this->nameMethodStructure(__METHOD__);
		if (!isset(self::$queries[$method]))
			$this->prepare($method,
				'SELECT id, `group`, level FROM '.$this->tableStructure.'
				WHERE '.$this->refPlanet.'=?'
			);

		self::$queries[$method]->execute(array($idPlanet));
		$elements = array();

		while ($e = self::$queries[$method]->fetchObject())
			$elements[] = $this->newElement($e->id, $e->group, $e->level, $idPlanet);
		return $elements;
	}

	/**
	 * @param int $id_user
	 * @return array : {ref_planet => {SW_Structure_List, ...}, ...}
	 */
	public function selectListAll($id_user)
	{
		$sth = $this->pdo->query(
			'SELECT _l.id as id, _l.'.$this->refStructure.' as ref_structure, _s.'.$this->refPlanet.' as _p, _l.level as level, duration, time_end FROM '.$this->tableStructure.' as _s
			JOIN '.$this->tablePlanet.' as _p ON _s.'.$this->refPlanet.' = _p.id
			JOIN '.$this->tableList.' as _l ON _s.id = _l.'.$this->refStructure.'
			WHERE '.$this->refPlayer.'='.$id_user,
			PDO::FETCH_OBJ
		);

		$lists = array();
		while ($l = $sth->fetchObject())
		{
			$p = (int)$e->ref_planet;
			if (false === isset($lists[$p]))
				$lists[$p] = array();
			$lists[$p][] = $this->newList($l->id, $l->ref_structure, $l->level, $l->duration, $l->time_end, $p);
		}

		return $lists;
	}

	/**
	 * @param int $idPlanet
	 * @return array : {SW_Structure_List, ...}
	 */
	public function selectListAllInPlanet($idPlanet)
	{
		$method = $this->nameMethodList(__METHOD__);
		if (!isset(self::$queries[$method]))
			$this->prepare($method,
				'SELECT _l.id, _l.'.$this->refStructure.' as ref_structure, _l.level as level, duration, time_end FROM '.$this->tableStructure.' as _s
				JOIN '.$this->tableList.' as _l ON _s.id = _l.'.$this->refStructure.'
				WHERE _s.'.$this->refPlanet.'=?'
			);

		self::$queries[$method]->execute(array($idPlanet));
		$lists = array();

		while ($l = self::$queries[$method]->fetchObject())
			$lists[] = $this->newList($l->id, $l->ref_structure, $l->level, $l->duration, $l->time_end, $idPlanet);

		return $lists;
	}

	/**
	 * Crée la table de la structure et celle de la list
	 * @param int $levelGroup = 4
	 * @param int $levelSize = 8
	 */
	public function createTable($levelGroup = 4, $levelSize = 8)
	{
		return $this->pdo->query(
			'CREATE TABLE IF NOT EXISTS '.$this->tableStructure.' (
				`id` int(11) NOT NULL AUTO_INCREMENT,
				'.$this->refPlanet.' int(11) NOT NULL,
				`group` tinyint('.((int)$levelGroup).') NOT NULL,
				`level` tinyint('.((int)$levelSize).') unsigned NOT NULL,
				PRIMARY KEY (`id`),
				UNIQUE KEY `structure_planet` ('.$this->refPlanet.',`group`)
			) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci AUTO_INCREMENT=1 ;'
		) && $this->pdo->query(
			'CREATE TABLE IF NOT EXISTS '.$this->tableList.' (
				`id` int(11) NOT NULL AUTO_INCREMENT,
				'.$this->refStructure.' int(11) NOT NULL,
				`level` tinyint('.((int)$levelSize).') unsigned NOT NULL,
				`duration` mediumint(9) NOT NULL,
				`time_end` int(11) NOT NULL,
				PRIMARY KEY (`id`),
				KEY `ref_id` ('.$this->refStructure.')
			) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci AUTO_INCREMENT=1 ;'
		);
	}
}